#include <my_header.h>
#include "netfd_queue.h"
#include "thread_pool.h"
#include "worker_thread_info.h"
#include "init_tcp.h"
#include "epoll.h"
#include "worker.h"
#include <signal.h>
#include <sys/wait.h>
//这里采用异步拉起同步机制,这个管道用来父进程与子进程进行通信使用,如果父进程
//收到了10号新号,就会给子进程发送退出表示,这样子进程再给若干个子线程发送flag=1标志位
//若干个子线程退出后,子进程才能退出,子进程退出后父进程才能退出
int exit_pipe[2];
void hanlder(int signal_num){
    printf("the server got a %d signal,the server is going to exit\n",signal_num);
    write(exit_pipe[1],"eixt",4);//给子进程发送退出信息
}
void print_banner(){
    printf("————————————————————————————————————————————————————————————————————-- \n");
    printf("//                           _ooOoo_                                  //\n");
    printf("//                          o8888888o                                //\n");
    printf("///                         88~ . ~88                                //\n");
    printf("///                         (| ^_^ |)                                //\n");
    printf("///                         O\\  =  /O                               //\n");
    printf("///                      ____/`---'\\____                            //\n");
    printf("///                    .'  \\|     |//  `.                           //\n");
    printf("///                   /  \\|||  :  |||//  \\                         //\n");
    printf("///                  /  _||||| -:- |||||- \\                         //\n");
    printf("///                  |   | \\\  -  /// |   |                         //\n");
    printf("///                  | \_|  ''\---/''  |   |                         //\n");
    printf("///                  \  .-\__  `-`  ___/-. /                         //\n");
    printf("///                ___`. .'  /--.--\  `. . ___                       //\n");
    printf("///              ."" '<  `.___\_<|>_/___.'  >'"".                    //\n");
    printf("///            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                   //\n");
    printf("///            \  \ `-.   \_ __\ /__ _/   .-` /  /                   //\n");
    printf("///      ========`-.____`-.___\_____/___.-`____.-'========           //\n");
    printf("///                           `=---='                                //\n");
    printf("///      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^          //\n");
    printf("///            佛祖保佑       永不宕机     永无BUG                   //\n");
    printf("/———————————————————————————————————————————————————————————————————— \n");
}
int main(int argc, char *argv[]){
    ARGS_CHECK(argc,4);
    pipe(exit_pipe);
    int fork_ret=fork();
    if(fork_ret){
        //这里是父进程!!
        close(exit_pipe[0]);
        signal(SIGUSR1,hanlder);
        wait(NULL);
        exit(EXIT_SUCCESS);
    }
    close(exit_pipe[1]);
    if (chdir(ROOTDIR) == -1) {
        perror("chdir to ROOTDIR failed");
        printf("请确保目录存在：%s\n", ROOTDIR);
        exit(1);
    }
    //如果走到这里就说明是子进程
    int init_worker_num=atoi(argv[3]);//获取初始化工人线程数量
    int sockfd=init_tcp(argv[1],argv[2]);//建立TCP连接
    int epfd=epoll_create(1);//创建epoll
    epoll_add(epfd,sockfd);//监听sockfd,连接用户
    epoll_add(epfd,exit_pipe[0]);//这个管道是父进程与子进程通信使用的管道如果父进程收到了退出的信号会想子进程发送一个flag
    thread_pool_info_t thread_pool_info;//创建共享资源,包含工人信息,锁,条件变量,连接netfd队列,退出表示等信息
    init_thread_pool_info(&thread_pool_info,init_worker_num);//初始化这些共享资源,但不创建工人线程
    print_banner();
    create_worker(&thread_pool_info);//创建工人线程

    struct epoll_event epoll_res[1];
    while(1){
        epoll_wait(epfd,epoll_res,1,-1);
        if(epoll_res[0].data.fd==sockfd){
            //响应连接
            int netfd =accept(sockfd,NULL,NULL);
            pthread_mutex_lock(&thread_pool_info.mutex);
            push_back_netfd(&thread_pool_info.netfd_queue,netfd);//将新建立的连接netfd入队列
            pthread_cond_broadcast(&thread_pool_info.cond);//收到新建立的netfd就给每个子线程都广播,
            pthread_mutex_unlock(&thread_pool_info.mutex);
        }else if(epoll_res[0].data.fd==exit_pipe[0]){
            //子进程收到父进程发来的退出标志,修改thread_pool_info中的flag,子线程这个时候要不在发送文件
            //要不在等待netfd,当监听到flag=1的时候就会自己退出线程,清理资源
            printf("I am the child process I got a exit signal from father process\n");
            pthread_mutex_lock(&thread_pool_info.mutex);
            thread_pool_info.exit_flag=1;
            pthread_cond_broadcast(&thread_pool_info.cond);//修改flag的值这样子线程就回到了系统正要退出,子线程完成自己的任务后就会自行退出
            pthread_mutex_unlock(&thread_pool_info.mutex);
            for(int i=0;i<thread_pool_info.worker_info.worker_num;i++){
                //子进程的退出条件是所有的子线程全部退出后才能退出
                pthread_join(thread_pool_info.worker_info.worker_arr[i],NULL);
            }
            printf("all the threads had quited,I am the child process,I have quited too\n");
            exit(EXIT_SUCCESS);
        }
    }
    return 0;
}

